package com.daxt.base.common.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.daxt.mapper.sys.*;
import com.daxt.model.dic.VersionsMarkType;
import com.daxt.model.service.archives.vo.ArchivesFonds;
import com.daxt.model.service.base.vo.*;
import com.daxt.service.UserService;
import com.daxt.utils.BaseUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.daxt.model.service.base.result.UserInfo;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.swagger.v3.oas.annotations.servers.Server;

@Service
public class UserInfoUtil {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private FunctionMapper functionMapper;
	@Autowired
	private RoleFunctionMapper roleFunctionMapper;
	@Autowired
	private UserRoleMapper userRoleMapper;
	@Autowired
	private UserDeptMapper userDeptMapper;
	@Autowired
	private ArchivesFondsMapper archivesFondsMapper;
	@Autowired
	private DeptMapper deptMapper;
	@Autowired
	private UserService userService;

	public static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {

			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {

		}
		return null;
	}


	public static Object unserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			// 反序列化
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {

		}
		return null;
	}


	@SuppressWarnings("unchecked")
	public <T> T  getLoginInfo(Class<T> clazz,RedisUtil redisUtil,HttpServletRequest request) {
		String token = request.getHeader("Authorization");
		if(StringUtils.isEmpty(token))
			return null;
		Map<String, Object> parseJWT1 = JwtUtil
				.parseJWT(JwtUtil.generateKey(JwtUtil.JWT_ALG, JwtUtil.JWT_RULE), token);
		if((boolean) parseJWT1.get("result")) {
		Jws<Claims> parseJWT = (Jws<Claims>) parseJWT1.get("code");
		String userId = parseJWT.getBody().getId();
		String subject = parseJWT.getBody().getSubject();
		String key=TokenInfo.getKey(userId,subject);
		Object userInfo=redisUtil.get(key);
		if(userInfo==null) {
			BaseUser selectById = userMapper.selectById(userId);
			UserInfo userInfoNew = new UserInfo();

				if("admin".equals(selectById.getUsername())) {
					QueryWrapper<Function> functionQueryWrapper=new QueryWrapper<Function>();
					functionQueryWrapper.eq("clientType", "ADMIN");
					functionQueryWrapper.eq("state", "1");
					functionQueryWrapper.orderByAsc("sort");
					List<Function> functions = functionMapper.selectList(functionQueryWrapper);
					userInfoNew.setResouces(functions);
					userInfoNew.setRole("admin");
				}else {
					QueryWrapper<UserRole> userRoleQueryWrapper=new QueryWrapper<UserRole>();
					userRoleQueryWrapper.eq("userId", selectById.getId());
					List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);
					List<Long> roleIds=new ArrayList<Long>();
					for (UserRole userRole : userRoles) {
						roleIds.add(userRole.getRoleId());
					}
					if(roleIds.size()>0) {
					QueryWrapper<Role> roleQueryWrapper=new QueryWrapper<Role>();
					roleQueryWrapper.in("id", roleIds);
					//roleQueryWrapper.eq("name", "admin");
					List<Role> roleList = roleMapper.selectList(roleQueryWrapper);
					if(roleList!=null&&roleList.size()>0) {
						//userInfo.setRole("admin");


						QueryWrapper<RoleFunction> roleFunctionQueryWrapper=new QueryWrapper<RoleFunction>();
						roleFunctionQueryWrapper.in("roleId", roleIds);
						List<RoleFunction> roleFunctions = roleFunctionMapper.selectList(roleFunctionQueryWrapper);
						List<String> functionIds=new ArrayList<String>();
						for (RoleFunction roleFunction : roleFunctions) {
							functionIds.add(roleFunction.getFunctionId());
						}
						QueryWrapper<Function> functionQueryWrapper=new QueryWrapper<Function>();
						functionQueryWrapper.eq("clientType", "ADMIN");
						functionQueryWrapper.eq("state", "1");
						functionQueryWrapper.in("id",functionIds);
						List<Function> functions = functionMapper.selectList(functionQueryWrapper);
						userInfoNew.setResouces(functions);

					}
					}

					}



			BeanUtils.copyProperties(selectById, userInfoNew);
			userInfo=userInfoNew;
			redisUtil.set(key,userInfo);
		}
		return JSON.parseObject(JSON.toJSONString(userInfo), clazz);
		}
		return null;
	}

	/**
	 * @description: 获取用户信息
	 *
	 * @author: lig
	 * @date: 2021/11/16
	 */
	public UserInfo  getLoginInfo(RedisUtil redisUtil,UserInfo loginUser) {
		String userId = loginUser.getId().toString();
		String from = loginUser.getFrom();
		String role = loginUser.getRole();
		String key = TokenInfo.getKey(userId,from);
		boolean hasKey = redisUtil.hasKey(key);
		if (!hasKey || StringUtils.isEmpty(role)) {
			BaseUser selectById = userMapper.selectById(userId);
//			UserInfo userInfoNew = new UserInfo();
//			UserInfo userInfoNew = new UserInfo();
			if(StringUtils.isEmpty(loginUser.getUsername()))loginUser.setUsername(selectById.getUsername());
			if(StringUtils.isEmpty(loginUser.getRealName()))loginUser.setRealName(selectById.getRealName());




//			if("admin".equals(selectById.getUsername())) {
//				QueryWrapper<Function> functionQueryWrapper=new QueryWrapper<Function>();
//				functionQueryWrapper.eq("clientType", "ADMIN");
//				functionQueryWrapper.eq("state", "1");
//				functionQueryWrapper.orderByAsc("sort");
//				List<Function> functions = functionMapper.selectList(functionQueryWrapper);
//				loginUser.setResouces(functions);
//				loginUser.setRole("admin");
////				userInfoNew.setResouces(functions);
////				userInfoNew.setRole("admin");
//			}else {
//				QueryWrapper<UserRole> userRoleQueryWrapper=new QueryWrapper<UserRole>();
//				userRoleQueryWrapper.eq("userId", selectById.getId());
//				List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);
//				List<Long> roleIds=new ArrayList<Long>();
//				for (UserRole userRole : userRoles) {
//					roleIds.add(userRole.getRoleId());/post
//				}
//				if(roleIds.size()>0) {
//					QueryWrapper<Role> roleQueryWrapper=new QueryWrapper<Role>();
//					roleQueryWrapper.in("id", roleIds);
//					//roleQueryWrapper.eq("name", "admin");
//					List<Role> roleList = roleMapper.selectList(roleQueryWrapper);
//					if(roleList!=null&&roleList.size()>0) {
//						//userInfo.setRole("admin");
//
//						loginUser.setRole(roleList.get(0).getName());
//
//						QueryWrapper<RoleFunction> roleFunctionQueryWrapper=new QueryWrapper<RoleFunction>();
//						roleFunctionQueryWrapper.in("roleId", roleIds);
//						List<RoleFunction> roleFunctions = roleFunctionMapper.selectList(roleFunctionQueryWrapper);
//						List<String> functionIds=new ArrayList<String>();
//						for (RoleFunction roleFunction : roleFunctions) {
//							functionIds.add(roleFunction.getFunctionId());
//						}
//
//						if(BaseUtil.listIsNotNullElement(functionIds)){
//							QueryWrapper<Function> functionQueryWrapper=new QueryWrapper<Function>();
////							functionQueryWrapper.eq("clientType", "ADMIN");
//							functionQueryWrapper.eq("clientType", "ADMIN");
//							functionQueryWrapper.eq("state", "1");
//							functionQueryWrapper.in("id",functionIds);
//							List<Function> functions = functionMapper.selectList(functionQueryWrapper);
////							userInfoNew.setResouces(functions);
//							loginUser.setResouces(functions);
//						}
//
//					}
//				}
//
//			}



		}

		//构造角色菜单
		userService.buildFunction(loginUser);



		if(!hasKey || (StringUtils.isEmpty(loginUser.getFondsId()) || StringUtils.isEmpty(loginUser.getDeptId()))){

			//获取公司对应的全宗
			QueryWrapper<UserDept> udQueryWrapper=new QueryWrapper<>();
			udQueryWrapper.eq("userId", loginUser.getId());
			UserDept ud = userDeptMapper.selectOne(udQueryWrapper);
			if(null != ud){

				Dept dept = deptMapper.selectById(ud.getDeptId());
				if(null != dept){
					loginUser.setDeptId(dept.getId().toString());
					loginUser.setDeptName(dept.getDeptName());

					List<Dept> deptList=deptMapper.getAllParentDept(dept.getId());

					if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_5)) {

						if(deptList.size()<=1){
							Long fondsId=deptList.get(0).getFondsId();
							if(fondsId!=null) loginUser.setFondsId(fondsId.toString());
							loginUser.setFondsName(deptList.get(0).getFondsName());
						}else{
							Long fondsId=deptList.get(1).getFondsId();
							if(fondsId!=null) loginUser.setFondsId(fondsId.toString());
							loginUser.setFondsName(deptList.get(1).getFondsName());
						}

					}else{
						if(!StringUtils.isEmpty(deptList.get(0).getFondsId())) loginUser.setFondsId(deptList.get(0).getFondsId().toString());
						loginUser.setFondsName(deptList.get(0).getFondsName());
					}
					ArchivesFonds af = archivesFondsMapper.selectById(loginUser.getFondsId());
					if(null != af){
						//loginUser.setFondsId(af.getId().toString());
						loginUser.setFondsName(af.getFondsName());
					}

				}



			}


		}







		redisUtil.set(key,loginUser);

		return loginUser;
	}


	@SuppressWarnings("unchecked")
	public static String  getKey(RedisUtil redisUtil,HttpServletRequest request) {
		String token = request.getHeader("Authorization");
		if(StringUtils.isEmpty(token))
			return null;
		Map<String, Object> parseJWT1 = JwtUtil
				.parseJWT(JwtUtil.generateKey(JwtUtil.JWT_ALG, JwtUtil.JWT_RULE), token);
		if((boolean) parseJWT1.get("result")) {
		Jws<Claims> parseJWT = (Jws<Claims>) parseJWT1.get("code");
		String userId = parseJWT.getBody().getId();
		String subject = parseJWT.getBody().getSubject();
		String key=TokenInfo.getKey(userId,subject);
		return key;
		}
		return null;

	}

	public static void updateLogInfo(UserInfo userInfo, RedisUtil redisUtil, HttpServletRequest request) {
		String key = getKey(redisUtil, request);
		redisUtil.set(key,userInfo);
	}
}
